﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef Scale9Image_h__
#define Scale9Image_h__

#include <vector>
#include <string>
#include "../base/Math.h"
#include "../utility/SmartPtrDef.h"
#include "../base/Types.h"
#include "../base/Matrix.h"
#include "../render/IRender.h"

namespace SkyEngine2d
{
	
	class Render;
	class Material;
	class Scale9ImageCommand;
	class Camera;
	
	/*!
	 \brief 点9图
	*/
	class SGE_API Scale9Image
	{
	public:
		//! 使用图片创建9宫图
		/*!
		\param const std::wstring & file_name  图片的路径
		\param const Rect cap_insets 图片的可拉伸区域
		\return Scale9Image *
		*/
		static Scale9Image* create(const std::wstring& file_name, const Rect cap_insets);
	
		//! 通过精灵帧创建9宫图
		/*!
		\param const SpriteFrame & sprite_frame 精灵帧
		\param const Rect & cap_insets 图片的可拉伸区域
		\return Scale9Image *
		*/
		static Scale9Image* create(const SpriteFrameSharedPtr& sprite_frame, const Rect& cap_insets);
	
		//! 使用图片创建9宫图
		/*!
		\param const std::wstring & file_name  图片的路径
		\param const Rect cap_insets 图片的可拉伸区域
		\return std::unique_ptr<Scale9Image>
		*/
		static std::unique_ptr<Scale9Image> createUniquePtr(const std::wstring& file_name, const Rect cap_insets);
	
		//! 通过精灵帧创建9宫图
		/*!
		\param const SpriteFrame & sprite_frame 精灵帧
		\param const Rect & cap_insets 图片的可拉伸区域
		\return std::unique_ptr<Scale9Image>
		*/
		static std::unique_ptr<Scale9Image> createUniquePtr(const SpriteFrameSharedPtr& sprite_frame, const Rect& cap_insets);
	
		~Scale9Image();
	
		void draw(IRender * render, const Matrix4X4& transform);
	
		void draw(IRender * render, const Rect& draw_rect, Camera* cramer);
	
		//! 横向缩放 
		/*!
		\param float sx  缩放的比例
		\return void
		\sa void setScalingY(float sy)
		*/
		void setScalingX(float sx);
	
		//! 纵向缩放
		/*!
		\param float sy 缩放比例
		\return void
		\sa void setScalingX(float sx)
		*/
		void setScalingY(float sy);
	
		//! 设置图片的显示尺寸 
		/*!
		\param const Size & size 尺寸
		\return void
		图片会根据该设置值进行适当的缩放
		\sa const Size & getDisplaySize()const
		*/
		void setDisplaySize(const Size& size);
	
		//! 获取图片当前的显示尺寸
		/*!
		\return const Size &
		\sa void setDisplaySize(const Size & size)
		*/
		const Size& getDisplaySize()const;
	
		//! 获取图片的原始尺寸大小 
		/*!
		\return const Size &
		\sa const Size & getDisplaySize()const
		*/
		const Size& getImageSize()const;
	
	protected:
		Scale9Image();
	
		bool init(const std::wstring& file_name, const Rect cap_insets);
		bool init(const SpriteFrameSharedPtr& sprite_frame, const Rect cap_insets);
		void setCapInsets(const Rect& cap_insets);
		void update();
		void updateMat(const Matrix4X4& mat);
	
		//! 更新水平方向的顶点，相当于进行水平方向的缩放处理 
		/*!
		\param float now_width 现在更新的宽度
		\return void
		\sa void updateVertexVertical (float now_height)
		*/
		void updateVertexHorizontal(float now_width);
	
		//! 更新垂直方向的定点，相当于进行垂直方向的缩放处理
		/*!
		\param float now_height 现在更新的高度
		\return void
		\sa void updateVertexHorizontal(float now_width)
		*/
		void updateVertexVertical(float now_height);
	
	private:
	
		SpriteFrameSharedPtr m_spriteFrame;
		std::shared_ptr<Material> m_material;
		std::vector<V2C4T2_Quad> m_quads;
		Rect m_imageRect; //图片的尺寸矩形
		Rect m_capInsets; //9宫格图片中心部分的矩形
		Rect m_textureRect; //纹理的尺寸
		std::unique_ptr<Scale9ImageCommand>  m_cmd; /*!< 渲染命令. */
		std::vector<VertexPositionTexture>   m_originalVertexBuffer; /*!< 原始数据 - 顶点缓存. */
		std::vector<VertexPositionTexture>   m_vertexBuffer;
		std::vector<VertexPositionTexture>   m_tempVertexBuffer;/*!< 经过计算的顶点数据 最后会传入 渲染指令 . */
		Matrix4X4 m_mat;					//矩阵信息
		bool		m_isUpdateVertexDate;  /*!< 是否更新顶点数据. */
		Size	m_displaySize;			/*!< 图片最终显示的尺寸. */
		Rect    m_lastDrawRect;				//上一次绘制的矩形
	};
	
}

#endif // Scale9Image_h__
